ngl: Use fp16 for colors
authorMatthias Clasen <mclasen@redhat.com>
Wed, 7 Apr 2021 01:55:50 +0000 (21:55 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 8 Apr 2021 01:30:43 +0000 (21:30 -0400)
This reduces the size of our Vertex struct from
48 to 32 bytes. It would be nicer if we could store
the colors in fp16 format in the rendernodes, and
avoid conversion here. But this is still good.

gsk/meson.build
gsk/ngl/fp16private.h [new file with mode: 0644]
gsk/ngl/gsknglcommandqueue.c
gsk/ngl/gsknglrenderjob.c
gsk/ngl/gskngltypesprivate.h

index 5c381b51c9b6b22cbe9fe9c7ca30b8273fcc740a..11be6a03f62b88d1c855d99ae6688a22179af4b6 100644 (file)
@@ -221,6 +221,7 @@ libgsk = static_library('gsk',
     '-DGTK_COMPILATION',
     '-DG_LOG_DOMAIN="Gsk"',
     '-DG_LOG_STRUCTURED=1',
+    '-mf16c'
   ] + common_cflags,
   link_with: libgdk,
 )
diff --git a/gsk/ngl/fp16private.h b/gsk/ngl/fp16private.h
new file mode 100644 (file)
index 0000000..b285bf4
--- /dev/null
@@ -0,0 +1,111 @@
+/* ninesliceprivate.h
+ *
+ * Copyright 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef __FP16_PRIVATE_H__
+#define __FP16_PRIVATE_H__
+
+#include <glib.h>
+#include <graphene.h>
+
+#ifdef GRAPHENE_USE_SSE
+#include <immintrin.h>
+#endif
+
+G_BEGIN_DECLS
+
+#ifdef GRAPHENE_USE_SSE
+
+static inline void
+float_to_half4 (const float f[4],
+                guint16     h[4])
+{
+  __m128 s = _mm_loadu_ps (f);
+  __m128i i = _mm_cvtps_ph (s, 0);
+  _mm_storel_epi64 ((__m128i*)h, i);
+}
+
+static inline void
+half_to_float4 (const guint16 h[4],
+                float         f[4])
+{
+  __m128i i = _mm_loadl_epi64 ((__m128i_u const *)h);
+  __m128 s = _mm_cvtph_ps (i);
+  _mm_store_ps (f, s);
+}
+
+#else  /* GRAPHENE_USE_SSE */
+
+static inline guint
+as_uint (const float x)
+{
+  return *(guint*)&x;
+}
+
+static inline float
+as_float (const guint x)
+{
+  return *(float*)&x;
+}
+
+// IEEE-754 16-bit floating-point format (without infinity): 1-5-10
+
+static inline float
+half_to_float (const guint16 x)
+{
+  const guint e = (x&0x7C00)>>10; // exponent
+  const guint m = (x&0x03FF)<<13; // mantissa
+  const guint v = as_uint((float)m)>>23;
+  return as_float((x&0x8000)<<16 | (e!=0)*((e+112)<<23|m) | ((e==0)&(m!=0))*((v-37)<<23|((m<<(150-v))&0x007FE000)));
+}
+
+static inline guint16
+float_to_half (const float x)
+{
+  const guint b = as_uint(x)+0x00001000; // round-to-nearest-even
+  const guint e = (b&0x7F800000)>>23; // exponent
+  const guint m = b&0x007FFFFF; // mantissa
+  return (b&0x80000000)>>16 | (e>112)*((((e-112)<<10)&0x7C00)|m>>13) | ((e<113)&(e>101))*((((0x007FF000+m)>>(125-e))+1)>>1) | (e>143)*0x7FFF; // sign : normalized : denormalized : saturate
+}
+
+static inline void
+float_to_half4 (const float f[4],
+                guint16     h[4])
+{
+  h[0] = float_to_half (f[0]);
+  h[1] = float_to_half (f[1]);
+  h[2] = float_to_half (f[2]);
+  h[3] = float_to_half (f[3]);
+}
+
+static inline void
+half_to_float4 (const guint16 h[4],
+                float         f[4])
+{
+  f[0] = half_to_float (h[0]);
+  f[1] = half_to_float (h[1]);
+  f[2] = half_to_float (h[2]);
+  f[3] = half_to_float (h[3]);
+}
+
+#endif  /* GRAPHENE_USE_SSE */
+
+G_END_DECLS
+
+#endif
index e160076c572522f0fc527c0b26a9fd3b62403a93..bdfef2f35cefdbec6c38dec5ec5f5088af7885d3 100644 (file)
@@ -1003,13 +1003,13 @@ gsk_ngl_command_queue_execute (GskNglCommandQueue   *self,
 
   /* 2 = color location */
   glEnableVertexAttribArray (2);
-  glVertexAttribPointer (2, 4, GL_FLOAT, GL_FALSE,
+  glVertexAttribPointer (2, 4, GL_HALF_FLOAT, GL_FALSE,
                          sizeof (GskNglDrawVertex),
                          (void *) G_STRUCT_OFFSET (GskNglDrawVertex, color));
 
   /* 3 = color2 location */
   glEnableVertexAttribArray (3);
-  glVertexAttribPointer (3, 4, GL_FLOAT, GL_FALSE,
+  glVertexAttribPointer (3, 4, GL_HALF_FLOAT, GL_FALSE,
                          sizeof (GskNglDrawVertex),
                          (void *) G_STRUCT_OFFSET (GskNglDrawVertex, color2));
 
index 3e823dedabe489279c123410ce241254df4853e5..ecaadc745827f65b2ad30fd496d533a751d5d28b 100644 (file)
@@ -43,6 +43,7 @@
 #include "gsknglshadowlibraryprivate.h"
 
 #include "ninesliceprivate.h"
+#include "fp16private.h"
 
 #define ORTHO_NEAR_PLANE   -10000
 #define ORTHO_FAR_PLANE     10000
@@ -884,6 +885,13 @@ gsk_ngl_render_job_update_clip (GskNglRenderJob     *job,
   return TRUE;
 }
 
+static inline void
+rgba_to_half (const GdkRGBA *c,
+              guint16        h[4])
+{
+  float_to_half4 ((const float *)c, h);
+}
+
 /* fill_vertex_data */
 static void
 gsk_ngl_render_job_draw_coords (GskNglRenderJob *job,
@@ -898,13 +906,16 @@ gsk_ngl_render_job_draw_coords (GskNglRenderJob *job,
                                 const GdkRGBA   *color)
 {
   GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
+  guint16 c[4];
+
+  rgba_to_half (color, c);
 
-  vertices[0] = (GskNglDrawVertex) { { min_x, min_y }, { min_u, min_v }, { color->red, color->green, color->blue, color->alpha } };
-  vertices[1] = (GskNglDrawVertex) { { min_x, max_y }, { min_u, max_v }, { color->red, color->green, color->blue, color->alpha } };
-  vertices[2] = (GskNglDrawVertex) { { max_x, min_y }, { max_u, min_v }, { color->red, color->green, color->blue, color->alpha } };
-  vertices[3] = (GskNglDrawVertex) { { max_x, max_y }, { max_u, max_v }, { color->red, color->green, color->blue, color->alpha } };
-  vertices[4] = (GskNglDrawVertex) { { min_x, max_y }, { min_u, max_v }, { color->red, color->green, color->blue, color->alpha } };
-  vertices[5] = (GskNglDrawVertex) { { max_x, min_y }, { max_u, min_v }, { color->red, color->green, color->blue, color->alpha } };
+  vertices[0] = (GskNglDrawVertex) { { min_x, min_y }, { min_u, min_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[1] = (GskNglDrawVertex) { { min_x, max_y }, { min_u, max_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[2] = (GskNglDrawVertex) { { max_x, min_y }, { max_u, min_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[3] = (GskNglDrawVertex) { { max_x, max_y }, { max_u, max_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[4] = (GskNglDrawVertex) { { min_x, max_y }, { min_u, max_v }, { c[0], c[1], c[2],c[3] } };
+  vertices[5] = (GskNglDrawVertex) { { max_x, min_y }, { max_u, min_v }, { c[0], c[1], c[2],c[3] } };
 }
 
 /* load_vertex_data_with_region */
@@ -1658,7 +1669,7 @@ gsk_ngl_render_job_visit_border_node (GskNglRenderJob     *job,
                                       const GskRenderNode *node)
 {
   const GskRoundedRect *rounded_outline = gsk_border_node_get_outline (node);
-  const GdkRGBA *c = gsk_border_node_get_colors (node);
+  const GdkRGBA *colors = gsk_border_node_get_colors (node);
   const float *widths = gsk_border_node_get_widths (node);
   struct {
     float w;
@@ -1669,6 +1680,7 @@ gsk_ngl_render_job_visit_border_node (GskNglRenderJob     *job,
   float max_x = min_x + node->bounds.size.width;
   float max_y = min_y + node->bounds.size.height;
   GskRoundedRect outline;
+  guint16 c[4];
 
   memset (sizes, 0, sizeof sizes);
 
@@ -1712,52 +1724,60 @@ gsk_ngl_render_job_visit_border_node (GskNglRenderJob     *job,
     {
       GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-      vertices[0] = (GskNglDrawVertex) { { min_x,              min_y              }, { 0, 1 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha } };
-      vertices[1] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha } };
-      vertices[2] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha } };
+      rgba_to_half (&colors[0], c);
 
-      vertices[3] = (GskNglDrawVertex) { { max_x - sizes[1].w, min_y + sizes[1].h }, { 1, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha } };
-      vertices[4] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha } };
-      vertices[5] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha } };
+      vertices[0] = (GskNglDrawVertex) { { min_x,              min_y              }, { 0, 1 }, { c[0], c[1], c[2], c[3] } };
+      vertices[1] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[2] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0], c[1], c[2], c[3] } };
+
+      vertices[3] = (GskNglDrawVertex) { { max_x - sizes[1].w, min_y + sizes[1].h }, { 1, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[4] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 0, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[5] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0], c[1], c[2], c[3] } };
     }
 
   if (widths[1] > 0)
     {
       GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-      vertices[0] = (GskNglDrawVertex) { { max_x - sizes[1].w, min_y + sizes[1].h }, { 0, 1 }, { c[1].red, c[1].green, c[1].blue, c[1].alpha } };
-      vertices[1] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, { c[1].red, c[1].green, c[1].blue, c[1].alpha } };
-      vertices[2] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[1].red, c[1].green, c[1].blue, c[1].alpha } };
+      rgba_to_half (&colors[1], c);
+
+      vertices[0] = (GskNglDrawVertex) { { max_x - sizes[1].w, min_y + sizes[1].h }, { 0, 1 }, { c[0], c[1], c[2], c[3] } };
+      vertices[1] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[2] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0], c[1], c[2], c[3] } };
 
-      vertices[3] = (GskNglDrawVertex) { { max_x,              max_y              }, { 1, 0 }, { c[1].red, c[1].green, c[1].blue, c[1].alpha } };
-      vertices[4] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, { c[1].red, c[1].green, c[1].blue, c[1].alpha } };
-      vertices[5] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[1].red, c[1].green, c[1].blue, c[1].alpha } };
+      vertices[3] = (GskNglDrawVertex) { { max_x,              max_y              }, { 1, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[4] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 0, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[5] = (GskNglDrawVertex) { { max_x,              min_y              }, { 1, 1 }, { c[0], c[1], c[2], c[3] } };
     }
 
   if (widths[2] > 0)
     {
       GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-      vertices[0] = (GskNglDrawVertex) { { min_x + sizes[3].w, max_y - sizes[3].h }, { 0, 1 }, { c[2].red, c[2].green, c[2].blue, c[2].alpha } };
-      vertices[1] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[2].red, c[2].green, c[2].blue, c[2].alpha } };
-      vertices[2] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, { c[2].red, c[2].green, c[2].blue, c[2].alpha } };
+      rgba_to_half (&colors[2], c);
+
+      vertices[0] = (GskNglDrawVertex) { { min_x + sizes[3].w, max_y - sizes[3].h }, { 0, 1 }, { c[0], c[1], c[2], c[3] } };
+      vertices[1] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[2] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, { c[0], c[1], c[2], c[3] } };
 
-      vertices[3] = (GskNglDrawVertex) { { max_x,              max_y              }, { 1, 0 }, { c[2].red, c[2].green, c[2].blue, c[2].alpha } };
-      vertices[4] = (GskNglDrawVertex) { { min_x            ,  max_y              }, { 0, 0 }, { c[2].red, c[2].green, c[2].blue, c[2].alpha } };
-      vertices[5] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, { c[2].red, c[2].green, c[2].blue, c[2].alpha } };
+      vertices[3] = (GskNglDrawVertex) { { max_x,              max_y              }, { 1, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[4] = (GskNglDrawVertex) { { min_x            ,  max_y              }, { 0, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[5] = (GskNglDrawVertex) { { max_x - sizes[2].w, max_y - sizes[2].h }, { 1, 1 }, { c[0], c[1], c[2], c[3] } };
     }
 
   if (widths[3] > 0)
     {
       GskNglDrawVertex *vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-      vertices[0] = (GskNglDrawVertex) { { min_x,              min_y              }, { 0, 1 }, { c[3].red, c[3].green, c[3].blue, c[3].alpha } };
-      vertices[1] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[3].red, c[3].green, c[3].blue, c[3].alpha } };
-      vertices[2] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, { c[3].red, c[3].green, c[3].blue, c[3].alpha } };
+      rgba_to_half (&colors[3], c);
 
-      vertices[3] = (GskNglDrawVertex) { { min_x + sizes[3].w, max_y - sizes[3].h }, { 1, 0 }, { c[3].red, c[3].green, c[3].blue, c[3].alpha } };
-      vertices[4] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[3].red, c[3].green, c[3].blue, c[3].alpha } };
-      vertices[5] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, { c[3].red, c[3].green, c[3].blue, c[3].alpha } };
+      vertices[0] = (GskNglDrawVertex) { { min_x,              min_y              }, { 0, 1 }, { c[0], c[1], c[2], c[3] } };
+      vertices[1] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[2] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, { c[0], c[1], c[2], c[3] } };
+
+      vertices[3] = (GskNglDrawVertex) { { min_x + sizes[3].w, max_y - sizes[3].h }, { 1, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[4] = (GskNglDrawVertex) { { min_x,              max_y              }, { 0, 0 }, { c[0], c[1], c[2], c[3] } };
+      vertices[5] = (GskNglDrawVertex) { { min_x + sizes[0].w, min_y + sizes[0].h }, { 1, 1 }, { c[0], c[1], c[2], c[3] } };
     }
 
   gsk_ngl_render_job_end_draw (job);
@@ -1775,8 +1795,8 @@ gsk_ngl_render_job_visit_css_background (GskNglRenderJob     *job,
                                          const GskRenderNode *node2)
 {
   const GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
-  const GdkRGBA *c2 = gsk_color_node_get_color (child);
-  const GdkRGBA *c = gsk_border_node_get_colors (node2);
+  const GdkRGBA *color = gsk_border_node_get_colors (node2);
+  const GdkRGBA *color2 = gsk_color_node_get_color (child);
   const GskRoundedRect *rounded_outline = gsk_border_node_get_outline (node2);
   const float *widths = gsk_border_node_get_widths (node2);
   float min_x = job->offset_x + node2->bounds.origin.x;
@@ -1785,10 +1805,14 @@ gsk_ngl_render_job_visit_css_background (GskNglRenderJob     *job,
   float max_y = min_y + node2->bounds.size.height;
   GskRoundedRect outline;
   GskNglDrawVertex *vertices;
+  guint16 c[4], c2[4];
 
   if (node_is_invisible (node2))
     return;
 
+  rgba_to_half (&color[0], c);
+  rgba_to_half (color2, c2);
+
   gsk_ngl_render_job_transform_rounded_rect (job, rounded_outline, &outline);
 
   gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, filled_border));
@@ -1803,12 +1827,12 @@ gsk_ngl_render_job_visit_css_background (GskNglRenderJob     *job,
 
   vertices = gsk_ngl_command_queue_add_vertices (job->command_queue);
 
-  vertices[0] = (GskNglDrawVertex) { { min_x, min_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[1] = (GskNglDrawVertex) { { min_x, max_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[2] = (GskNglDrawVertex) { { max_x, min_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[3] = (GskNglDrawVertex) { { max_x, max_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[4] = (GskNglDrawVertex) { { min_x, max_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
-  vertices[5] = (GskNglDrawVertex) { { max_x, min_y }, { 0, 0 }, { c[0].red, c[0].green, c[0].blue, c[0].alpha }, { c2->red, c2->green, c2->blue, c2->alpha } };
+  vertices[0] = (GskNglDrawVertex) { { min_x, min_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], c2[2], c2[3] } };
+  vertices[1] = (GskNglDrawVertex) { { min_x, max_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], c2[2], c2[3] } };
+  vertices[2] = (GskNglDrawVertex) { { max_x, min_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], c2[2], c2[3] } };
+  vertices[3] = (GskNglDrawVertex) { { max_x, max_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], c2[2], c2[3] } };
+  vertices[4] = (GskNglDrawVertex) { { min_x, max_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], c2[2], c2[3] } };
+  vertices[5] = (GskNglDrawVertex) { { max_x, min_y }, { 0, 0 }, { c[0], c[1], c[2], c[3] }, { c2[0], c2[1], c2[2], c2[3] } };
 
   gsk_ngl_render_job_end_draw (job);
 }
@@ -2690,7 +2714,7 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
   guint last_texture = 0;
   GskNglDrawVertex *vertices;
   guint used = 0;
-  GdkRGBA c;
+  guint16 c[4];
   const PangoGlyphInfo *gi;
   guint i;
   int yshift;
@@ -2703,9 +2727,9 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
    * We tell the shader by setting the color to vec4(-1).
    */
   if (!force_color && gsk_text_node_has_color_glyphs (node))
-    c = (GdkRGBA) { -1.f, -1.f, -1.f, -1.f };
+    rgba_to_half (&(GdkRGBA){ -1.f, -1.f, -1.f, -1.f }, c);
   else
-    c = *color;
+    rgba_to_half (color, c);
 
   lookup.font = (PangoFont *)font;
   lookup.scale = (guint) (text_scale * 1024);
@@ -2783,13 +2807,13 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
       glyph_x2 = glyph_x + glyph->ink_rect.width;
       glyph_y2 = glyph_y + glyph->ink_rect.height;
 
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y  }, { tx,  ty  }, { c.red, c.green, c.blue, c.alpha } };
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y2 }, { tx,  ty2 }, { c.red, c.green, c.blue, c.alpha } };
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y  }, { tx2, ty  }, { c.red, c.green, c.blue, c.alpha } };
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y  }, { tx,  ty  }, { c[0], c[1], c[2], c[3] } };
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y2 }, { tx,  ty2 }, { c[0], c[1], c[2], c[3] } };
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y  }, { tx2, ty  }, { c[0], c[1], c[2], c[3] } };
 
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y2 }, { tx2, ty2 }, { c.red, c.green, c.blue, c.alpha } };
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y2 }, { tx,  ty2 }, { c.red, c.green, c.blue, c.alpha } };
-      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y  }, { tx2, ty  }, { c.red, c.green, c.blue, c.alpha } };
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y2 }, { tx2, ty2 }, { c[0], c[1], c[2], c[3] } };
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x,  glyph_y2 }, { tx,  ty2 }, { c[0], c[1], c[2], c[3] } };
+      *(vertices++) = (GskNglDrawVertex) { { glyph_x2, glyph_y  }, { tx2, ty  }, { c[0], c[1], c[2], c[3] } };
 
       batch->draw.vbo_count += GSK_NGL_N_VERTICES;
       used++;
index a65130c19fc3af2bc91a407c7ff05e772888ba89..dda4365271bb3c38c70d3f9fda14eeafb63d77f1 100644 (file)
@@ -55,8 +55,8 @@ struct _GskNglDrawVertex
 {
   float position[2];
   float uv[2];
-  float color[4];
-  float color2[4];
+  guint16 color[4];
+  guint16 color2[4];
 };
 
 G_END_DECLS